<?php

namespace App\Utils;


class NumberUtil
{
    /**
     * 十进制转字符串
     * @param $A
     * @return string
     */
    public static function BIntDecToStr($A): string
    {
        $Result = "";

        while ($A > 0) {
            $Result = Chr(bcmod($A, 256)) . $Result;
            $A = bcdiv($A, 256);
        }
        return $Result;
    }

    /**
     * 字符串转十进制
     * @param $A
     * @return string
     */
    public static function BIntStrToDec($A): string
    {
        $Result = "";

        for ($i = 0; $i < StrLen($A); $i++) {
            $T = "1";
            for ($j = $i + 1; $j < StrLen($A); $j++) $T = bcmul($T, "256");
            $Result = bcadd($Result, bcmul(Ord($A[$i]), $T));
        }
        return $Result;
    }

    /**
     * 十进制转十六进制
     * @param $A
     * @return string
     */
    function BIntDecToHex($A): string
    {
        $Result = "";

        while ($A > 0) {
            $Result = base_convert(bcmod($A, 16), 10, 16) . $Result;
            $A = bcdiv($A, 16);
        }
        return $Result;
    }

    /**
     * 十六进制转十进制
     * @param $A
     * @return string
     */
    public static function BIntHexToDec($A): string
    {
        $Result = "";

        for ($i = 0; $i < StrLen($A); $i++) {
            $T = "1";
            for ($j = $i + 1; $j < StrLen($A); $j++) $T = bcmul($T, "16");
            $Result = bcadd($Result, bcmul(base_convert($A[$i], 16, 10), $T));
        }
        return $Result;
    }

    /**
     * 十进制转三十二进制
     * @param $A
     * @return string
     */
    public static function BIntDecToBase32($A): string
    {
        $Result = "";

        while ($A > 0) {
            $Result = base_convert(bcmod($A, 32), 10, 32) . $Result;
            $A = bcdiv($A, 32);
        }

        return $Result;
    }

    /**
     * 三十二进制转十进制
     * @param $A
     * @return string
     */
    public static function BIntBase32ToDec($A): string
    {
        $Result = "";

        try {
            for ($i = 0; $i < StrLen($A); $i++) {
                $T = "1";
                for ($j = $i + 1; $j < StrLen($A); $j++) $T = bcmul($T, "32");
                $Result = bcadd($Result, bcmul(base_convert($A[$i], 32, 10), $T));
            }
        } catch (\Throwable $e) {
            Logger::getInstance()->error(sprintf("BIntBase32ToDec错误, 参数A: %s, errorMsg: %s",
                $A, $e->getMessage()));
        }

        return $Result;
    }

    /**
     * 十进制转六十四进制
     * @param $A
     * @return string
     */
    public static function BIntDecToBase64($A): string
    {
        return base64_encode(self::BIntDecToStr($A));
    }

    /**
     * 六十四进制转十进制
     * @param $A
     * @return mixed
     */
    public static function BIntBase64ToDec($A)
    {
        return self::BIntStrToDec(base64_decode($A));
    }

    /**
     * 十进制转二进制
     * @param $A
     * @return string
     */
    public static function BIntDecToBin($A): string
    {
        $Result = "";

        while ($A > 0) {
            $Result = bcmod($A, 2) . $Result;
            $A = bcdiv($A, 2);
        }
        return $Result;
    }

    /**
     * 十六进制转二进制
     * @param $A
     * @return string
     */
    public static function BIntHexToBin($A): string
    {
        $Result = "";
        $Len = StrLen($A);
        for ($i = 0; $i < $Len; $i++) {
            $T = base_convert($A[$i], 16, 2);
            if ($i > 0) {
                $n = StrLen($T);
                if ($n == 1) $T = "000" . $T;
                elseif ($n == 2) $T = "00" . $T;
                elseif ($n == 3) $T = "0" . $T;
            }
            $Result = $Result . $T;
        }
        return $Result;
    }

    /**
     * 六十四进制转二进制
     * @param $A
     * @return mixed
     */
    public static function BIntBase64ToBin($A)
    {
        return self::BIntDecToBin(self::BIntBase64ToDec($A));
    }
}